// convert.c
#include "convert.h"
#include <math.h>

// 主转换函数（使用两层 switch-case）
Bool convert(Bool en, DataType inType, void* in, DataType outType, void* out) {
  // 检查使能参数
  if(!en) {
    return false;
  }
  // 空指针和类型有效性检查
  if(!in || !out || inType >= TYPE_COUNT || outType >= TYPE_COUNT) {
    return false;
  }

  // 第一层 switch：输入类型
  switch(inType) {
    case TYPE_BYTE: { // uint8_t Byte
      Byte val = *(const Byte*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_WORD: { // uint16_t
      Word val = *(const Word*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_DWORD: { // uint32_t
      DWord val = *(const DWord*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_LWORD: { // uint64_t
      LWord val = *(const LWord*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_SINT: { // int8_t 小的有符号转大的无符号需要两步
      SInt val = *(const SInt*) in;
      switch(outType) {
        case TYPE_BYTE: // 8
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD: // 16 🎈
          *(Word*) out = (Word) (uint8_t) val;
          return true;
        case TYPE_DWORD: // 32
          *(DWord*) out = (DWord) (uint8_t) val;
          return true;
        case TYPE_LWORD: // 64
          *(LWord*) out = (LWord) (uint8_t) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT: // 16
          *(UInt*) out = (UInt) (uint8_t) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) (uint8_t) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) (uint8_t) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) (uint8_t) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_USINT: { // uint8_t
      USInt val = *(const USInt*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_INT: { // int16_t 小的有符号转大的无符号需要两步
      Int val = *(const Int*) in;
      switch(outType) {
        case TYPE_BYTE: // 8
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD: // 16
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD: // 32
          *(DWord*) out = (DWord) (uint16_t) val;
          return true;
        case TYPE_LWORD: // 64
          *(LWord*) out = (LWord) (uint16_t) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT: // 32
          *(UDInt*) out = (UDInt) (uint16_t) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT: // 64
          *(ULInt*) out = (ULInt) (uint16_t) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_UINT: {
      UInt val = *(const UInt*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_DINT: { // int32_t
      DInt val = *(const DInt*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) (uint32_t) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) (uint32_t) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_UDINT: {
      UDInt val = *(const UDInt*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_LINT: { // int64_t
      LInt val = *(const LInt*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_ULINT: {
      ULInt val = *(const ULInt*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_REAL: {
      Real val = *(const Real*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_LREAL: {
      LReal val = *(const LReal*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_CHAR: { // int8_t
      Char val = *(const Char*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) (uint8_t) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) (uint8_t) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) (uint8_t) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) (uint8_t) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) (uint8_t) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) (uint8_t) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) (uint8_t) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_WCHAR: { // int16_t
      WChar val = *(const WChar*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) (uint16_t) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) (uint16_t) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) (uint16_t) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) (uint16_t) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    case TYPE_TIME: { // Time type
      Time val = *(const Time*) in;
      switch(outType) {
        case TYPE_BYTE:
          *(Byte*) out = (Byte) val;
          return true;
        case TYPE_WORD:
          *(Word*) out = (Word) val;
          return true;
        case TYPE_DWORD:
          *(DWord*) out = (DWord) val;
          return true;
        case TYPE_LWORD:
          *(LWord*) out = (LWord) val;
          return true;
        case TYPE_SINT:
          *(SInt*) out = (SInt) val;
          return true;
        case TYPE_USINT:
          *(USInt*) out = (USInt) val;
          return true;
        case TYPE_INT:
          *(Int*) out = (Int) val;
          return true;
        case TYPE_UINT:
          *(UInt*) out = (UInt) val;
          return true;
        case TYPE_DINT:
          *(DInt*) out = (DInt) val;
          return true;
        case TYPE_UDINT:
          *(UDInt*) out = (UDInt) val;
          return true;
        case TYPE_LINT:
          *(LInt*) out = (LInt) val;
          return true;
        case TYPE_ULINT:
          *(ULInt*) out = (ULInt) val;
          return true;
        case TYPE_REAL:
          *(Real*) out = (Real) val;
          return true;
        case TYPE_LREAL:
          *(LReal*) out = (LReal) val;
          return true;
        case TYPE_CHAR:
          *(Char*) out = (Char) val;
          return true;
        case TYPE_WCHAR:
          *(WChar*) out = (WChar) val;
          return true;
        case TYPE_TIME:
          *(Time*) out = (Time) val;
          return true;
        default:
          return false;
      }
    }
    default:

      return false;
  }
}
// convert(Bool en, DataType inType, void* in, DataType outType, void* out)
// 宏：生成单个转换函数
#define DEFINE_CONVERT_FUNC(out_type, in_type, out_type_t, in_type_t)                                                  \
  out_type_t in_type##_TO_##out_type(in_type_t in) {                                                                   \
    out_type_t out = 0;                                                                                                \
    convert(true, TYPE_##in_type, (void*) &in, TYPE_##out_type, (void*) &out);                                         \
    return out;                                                                                                        \
  }

// 宏：为单一输入类型生成 16 个转换函数
#define DEFINE_CONVERTERS_FOR_INPUT(in_type, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(BYTE, in_type, Byte, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(WORD, in_type, Word, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(DWORD, in_type, DWord, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(LWORD, in_type, LWord, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(SINT, in_type, SInt, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(USINT, in_type, USInt, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(INT, in_type, Int, in_type_t)                                                                    \
  DEFINE_CONVERT_FUNC(UINT, in_type, UInt, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(DINT, in_type, DInt, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(UDINT, in_type, UDInt, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(LINT, in_type, LInt, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(ULINT, in_type, ULInt, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(REAL, in_type, Real, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(LREAL, in_type, LReal, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(CHAR, in_type, Char, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(WCHAR, in_type, WChar, in_type_t)                                                                \
  DEFINE_CONVERT_FUNC(BOOL, in_type, Bool, in_type_t)                                                                  \
  DEFINE_CONVERT_FUNC(TIME, in_type, Time, in_type_t)

// 生成所有 256 个转换函数
DEFINE_CONVERTERS_FOR_INPUT(BYTE, Byte)
DEFINE_CONVERTERS_FOR_INPUT(WORD, Word)
DEFINE_CONVERTERS_FOR_INPUT(DWORD, DWord)
DEFINE_CONVERTERS_FOR_INPUT(LWORD, LWord)
DEFINE_CONVERTERS_FOR_INPUT(SINT, SInt)
DEFINE_CONVERTERS_FOR_INPUT(USINT, USInt)
DEFINE_CONVERTERS_FOR_INPUT(INT, Int)
DEFINE_CONVERTERS_FOR_INPUT(UINT, UInt)
DEFINE_CONVERTERS_FOR_INPUT(DINT, DInt)
DEFINE_CONVERTERS_FOR_INPUT(UDINT, UDInt)
DEFINE_CONVERTERS_FOR_INPUT(LINT, LInt)
DEFINE_CONVERTERS_FOR_INPUT(ULINT, ULInt)
DEFINE_CONVERTERS_FOR_INPUT(REAL, Real)
DEFINE_CONVERTERS_FOR_INPUT(LREAL, LReal)
DEFINE_CONVERTERS_FOR_INPUT(CHAR, Char)
DEFINE_CONVERTERS_FOR_INPUT(WCHAR, WChar)
DEFINE_CONVERTERS_FOR_INPUT(BOOL, Bool)
DEFINE_CONVERTERS_FOR_INPUT(TIME, Time)

Bool Round(Bool en, InputType in_type, const void* in, OutputType out_type, void* out) {
  if(!en || !in || !out)
    return false;
  // 空指针和类型有效性检查
  if(!in || !out || in_type >= IN_TYPE_COUNT || out_type >= OUT_TYPE_COUNT) {
    return false;
  }

  double val = 0.0;

  // 根据输入类型读取并转换成double
  if(in_type == IN_TYPE_REAL) {
    val = (double) (*(const float*) in);
  } else if(in_type == IN_TYPE_LREAL) {
    val = *(const double*) in;
  } else {
    return false; // 不支持的输入类型
  }

  // 银行家舍入
  double roundedDouble = round(val);

  switch(out_type) {
    case OUT_TYPE_INT:
      *(int*) out = (int) roundedDouble;
      break;
    case OUT_TYPE_SINT:
      *(int8_t*) out = (int8_t) roundedDouble;
      break;
    case OUT_TYPE_DINT:
      *(int32_t*) out = (int32_t) roundedDouble;
      break;
    case OUT_TYPE_UINT:
      *(uint16_t*) out = (uint16_t) (roundedDouble);
      break;
    case OUT_TYPE_USINT:
      *(uint8_t*) out = (uint8_t) (roundedDouble);
      break;
    case OUT_TYPE_UDINT:
      *(uint32_t*) out = (uint32_t) (roundedDouble);
      break;
    case OUT_TYPE_LREAL:
      *(double*) out = roundedDouble;
      break;
    case OUT_TYPE_REAL:
      *(float*) out = (float) roundedDouble;
      break;
    default:
      return false;
  }
  return true;
}
Bool Ceil(Bool en, InputType in_type, const void* in, OutputType out_type, void* out) {
  if(!en || !in || !out)
    return false;

  if(!in || !out || in_type >= IN_TYPE_COUNT || out_type >= OUT_TYPE_COUNT) {
    return false;
  }

  double val = 0.0;

  // 根据输入类型读取并转换成double
  if(in_type == IN_TYPE_REAL) {
    val = (double) (*(const float*) in);
  } else if(in_type == IN_TYPE_LREAL) {
    val = *(const double*) in;
  } else {
    return false; // 不支持的输入类型
  }

  // 银行家舍入
  double roundedDouble = ceil(val);

  switch(out_type) {
    case OUT_TYPE_INT:
      *(int*) out = (int) roundedDouble;
      break;
    case OUT_TYPE_SINT:
      *(int8_t*) out = (int8_t) roundedDouble;
      break;
    case OUT_TYPE_DINT:
      *(int32_t*) out = (int32_t) roundedDouble;
      break;
    case OUT_TYPE_UINT:
      *(uint16_t*) out = (uint16_t) (roundedDouble);
      break;
    case OUT_TYPE_USINT:
      *(uint8_t*) out = (uint8_t) (roundedDouble);
      break;
    case OUT_TYPE_UDINT:
      *(uint32_t*) out = (uint32_t) (roundedDouble);
      break;
    case OUT_TYPE_LREAL:
      *(double*) out = roundedDouble;
      break;
    case OUT_TYPE_REAL:
      *(float*) out = (float) roundedDouble;
      break;
    default:
      return false;
  }
  return true;
}
Bool Floor(Bool en, InputType in_type, const void* in, OutputType out_type, void* out) {
  if(!en || !in || !out)
    return false;

  if(!in || !out || in_type >= IN_TYPE_COUNT || out_type >= OUT_TYPE_COUNT) {
    return false;
  }

  double val = 0.0;

  // 根据输入类型读取并转换成double
  if(in_type == IN_TYPE_REAL) {
    val = (double) (*(const float*) in);
  } else if(in_type == IN_TYPE_LREAL) {
    val = *(const double*) in;
  } else {
    return false; // 不支持的输入类型
  }

  // 银行家舍入
  double roundedDouble = floor(val);

  switch(out_type) {
    case OUT_TYPE_INT:
      *(int*) out = (int) roundedDouble;
      break;
    case OUT_TYPE_SINT:
      *(int8_t*) out = (int8_t) roundedDouble;
      break;
    case OUT_TYPE_DINT:
      *(int32_t*) out = (int32_t) roundedDouble;
      break;
    case OUT_TYPE_UINT:
      *(uint16_t*) out = (uint16_t) (roundedDouble);
      break;
    case OUT_TYPE_USINT:
      *(uint8_t*) out = (uint8_t) (roundedDouble);
      break;
    case OUT_TYPE_UDINT:
      *(uint32_t*) out = (uint32_t) (roundedDouble);
      break;
    case OUT_TYPE_LREAL:
      *(double*) out = roundedDouble;
      break;
    case OUT_TYPE_REAL:
      *(float*) out = (float) roundedDouble;
      break;
    default:
      return false;
  }
  return true;
}
